/**
 * Free6Category.java
 * 
 * FreeZzaph is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * FreeZzaph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.
 */

package freezzaph.plugins;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import freezzaph.exceptions.PluginException;
import freezzaph.exceptions.URLFetchException;
import freezzaph.plugins.util.URLFetcher;

/**
 * Category class that takes care of what is common
 * for the Free6 Categories.
 * 
 * @author FreeZzaph
 */
abstract class Free6Category extends Category {
	
	private static final Pattern link = Pattern.compile("<a.+?href=\"gallery.php\\?url=([^&]+)[^>]+?>([^<]+?)</a>");
	
	private int categoryId;
	private String mediaType;

	/**
	 * Construct a Free6Category.
	 * 
	 * @param name the name of the category
	 * @param description the description of the category
	 * @param filter the filter of the category
	 * @param categoryId the category's ID
	 * @param mediaType the media type of the category
	 */
	public Free6Category(String name, String description, String filter, int categoryId, String mediaType) {
		super(name, description, filter);
		this.categoryId = categoryId;
		this.mediaType = mediaType;
	}

	/*
	 * (non-Javadoc)
	 * @see freezzaph.plugins.Category#fetch(int, int)
	 */
	@Override final public URL[] fetch(int start, int count) {
		
		// Calculate offsets, start positions and counts
		int offset = start / 30 * 30;
		int realStart = offset % 30;
		int currentCount = 0;
		int realCount = count;
		if (realCount == -1) realCount = 30 - realStart;
		
		ArrayList<URL> urls = new ArrayList<URL>();
		HashMap<String, Object> duplicatePreventor = new HashMap<String, Object>(realCount);
		while (currentCount < realCount) {
			
			// Generate URL for this session
			URL categoryURL = null;
			try {
				categoryURL = new URL("http://free6.com/galleries.php?catId=" + categoryId + "&offset=" + offset + "&setPrefs=1&mediaType=" + mediaType + "&thumbView=0");
			} catch (MalformedURLException e) {
				// Won't happen
			}
			
			// Fetch (X)HTML data for parsing
			String sb;
			try {
				sb = URLFetcher.fetch(categoryURL);
			} catch (URLFetchException e) {
				throw new PluginException("Could not download URL list. Free6.com may not be accessible, or the plugin may need to be updated.", e);
			}
			
			Matcher m = link.matcher(sb);
			while (realStart > 0) {
				// If not starting at 0, fast forward
				//the matcher to the appropriate starting point
				m.find();
				realStart--;
			}
			while (m.find() && currentCount < realCount) {
				try {
					String path = URLDecoder.decode(m.group(1),"utf8");
					if (!duplicatePreventor.containsKey(path)) {
						// Ignore duplicates
						URL url = new URL("http://" + path);
						urls.add(url);
						currentCount++;
						duplicatePreventor.put(path, null);
					}
				} catch (IllegalArgumentException iae) {
					// When a URL is illegally encoded
					// Just ignore it.
				} catch (UnsupportedEncodingException e) {
					// Won't happen
				} catch (MalformedURLException e) {
					// When a URL is malformed
					// Just ignore it.
				}
			}
			
			// Go to next page
			offset += 30;
		}
		return urls.toArray(new URL[0]);
	}

}
